home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / x / volume0 / awm / part11 < prev    next >
Encoding:
Internet Message Format  |  1988-08-10  |  36.7 KB

  1. Path: uunet!wyse!mikew
  2. From: mikew@wyse.wyse.com (Mike Wexler)
  3. Newsgroups: comp.sources.x
  4. Subject: v00i012:  Ardent Window Manager, Part11/13
  5. Message-ID: <1635@wyse.wyse.com>
  6. Date: 10 Aug 88 22:00:55 GMT
  7. Sender: news@wyse.wyse.com
  8. Lines: 1360
  9. Approved: mikew@wyse.com
  10.  
  11. Submitted-by: unido!pcsbst!jkh (Jordan Hubbard)
  12. Posting-number: Volume 0, Issue 12
  13. Archive-name: awm/part11
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 11 (of 13)."
  22. # Contents:  awm/menus/menu.c
  23. # Wrapped by mikew@wyse on Mon Aug  8 12:01:48 1988
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f awm/menus/menu.c -a "${1}" != "-c" ; then 
  26.   echo shar: Will not over-write existing file \"awm/menus/menu.c\"
  27. else
  28. echo shar: Extracting \"awm/menus/menu.c\" \(34428 characters\)
  29. sed "s/^X//" >awm/menus/menu.c <<'END_OF_awm/menus/menu.c'
  30. X#ident   "%W% %G%"
  31. X
  32. X#ifndef lint
  33. X     static char sccs_id[] = "@(#)menu.c    2.1 12/16/87  Siemens Corporate Research and Support, Inc.";
  34. X#endif
  35. X
  36. X
  37. X/*
  38. X  RTL Menu Package Version 1.0
  39. X  by Joe Camaratta and Mike Berman, Siemens RTL, Princeton NJ, 1987
  40. X  
  41. X  menu.c: menu utility and support functions.
  42. X  
  43. X  Originally hacked by Adam J. Richter, based on the menu package for xterm.
  44. X  ( misc.c  X10/6.6 )
  45. X
  46. X  */
  47. X
  48. X/*
  49. X *
  50. X * Changed in various and subtle ways by Jordan Hubbard, Ardent Computer.
  51. X * February 1st, 1988: Removed dependence on oldX by nuking AssocTable
  52. X * stuff in favor of contexts. Added "label" panes, useful for titling
  53. X * purposes. Variable height items, variable fonts, pictoral panes
  54. X * (pixmaps) for cute graphic menus.
  55. X */
  56. X
  57. X/*
  58. X *
  59. X * Copyright 1987, 1988 by Ardent Computer Corporation, Sunnyvale, Ca.
  60. X *
  61. X * Copyright 1987 by Jordan Hubbard.
  62. X *
  63. X *
  64. X *                         All Rights Reserved
  65. X *
  66. X * Permission to use, copy, modify, and distribute this software and its
  67. X * documentation for any purpose and without fee is hereby granted,
  68. X * provided that the above copyright notice appear in all copies and that
  69. X * both that copyright notice and this permission notice appear in
  70. X * supporting documentation, and that the name of Ardent Computer
  71. X * Corporation or Jordan Hubbard not be used in advertising or publicity
  72. X * pertaining to distribution of the software without specific, written
  73. X * prior permission.
  74. X *
  75. X */
  76. X
  77. X
  78. X/*
  79. X  
  80. X  Copyright 1987 by
  81. X  Siemens Corporate Research and Support, Inc., Princeton, New Jersey
  82. X  
  83. X  Permission to use, copy, modify, and distribute this software
  84. X  and its documentation for any purpose and without fee is
  85. X  hereby granted, provided that the above copyright notice
  86. X  appear in all copies and that both that copyright notice and
  87. X  this permission notice appear in supporting documentation, and
  88. X  that the name of Siemens not be used in advertising or
  89. X  publicity pertaining to distribution of the software without
  90. X  specific, written prior permission.  Siemens makes no
  91. X  representations about the suitability of this software for any
  92. X  purpose.  It is provided "as is" without express or implied
  93. X  warranty.
  94. X  
  95. X  */
  96. X
  97. X/*
  98. X  
  99. X  Copyright 1985, 1986, 1987 by the Massachusetts Institute of Technology
  100. X  
  101. X  Permission to use, copy, modify, and distribute this
  102. X  software and its documentation for any purpose and without
  103. X  fee is hereby granted, provided that the above copyright
  104. X  notice appear in all copies and that both that copyright
  105. X  notice and this permission notice appear in supporting
  106. X  documentation, and that the name of M.I.T. not be used in
  107. X  advertising or publicity pertaining to distribution of the
  108. X  software without specific, written prior permission.
  109. X  M.I.T. makes no representations about the suitability of
  110. X  this software for any purpose.  It is provided "as is"
  111. X  without express or implied warranty.
  112. X  
  113. X  */
  114. X
  115. X/*
  116. X * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
  117. X *
  118. X *               All Rights Reserved
  119. X *
  120. X * Permission to use, copy, modify, and distribute this software and its
  121. X * documentation for any purpose and without fee is hereby granted,
  122. X * provided that the above copyright notice appear in all copies and that
  123. X * both that copyright notice and this permission notice appear in
  124. X * supporting documentation, and that the name of Digital Equipment
  125. X * Corporation not be used in advertising or publicity pertaining to
  126. X * distribution of the software without specific, written prior permission.
  127. X *
  128. X *
  129. X * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  130. X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  131. X * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  132. X * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  133. X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  134. X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  135. X * SOFTWARE.
  136. X */
  137. X
  138. X/* Got that?  Good! Now, there is actually some code in here.. */
  139. X
  140. X
  141. X#include <stdio.h>
  142. X#include "X11/Xlib.h"
  143. X#include "X11/cursorfont.h"
  144. X#include "X11/Xutil.h"
  145. X#include "X11/Intrinsic.h"
  146. X
  147. X#include "menu.h"
  148. X#include "menu.def.h"
  149. X#include "gray1.h"
  150. X#include "arrow_icon.h"
  151. X#include "dbug.h"
  152. X
  153. X#define MakeEven(x) ((x%2 == 0)? x : x-1)
  154. X
  155. X
  156. X#define InvertPlane        1
  157. X
  158. Xstatic char Check_MarkBits[] = {
  159. X     0x00, 0x01, 0x80, 0x01, 0xc0, 0x00, 0x60, 0x00,
  160. X     0x31, 0x00, 0x1b, 0x00, 0x0e, 0x00, 0x04, 0x00
  161. X     };
  162. X
  163. XMenu MenuDefault;
  164. X
  165. X/*
  166. X * the following have already been set my GetDefaults()
  167. X * by the time we get here.
  168. X */
  169. XXFontStruct *MFontInfo;
  170. XXFontStruct *MBoldFontInfo;
  171. Xint MBorderWidth, MPad, MDelta, MItemBorder;
  172. XPixel MForeground, MBackground, MBorder;
  173. X
  174. Xextern Boolean SaveUnder;
  175. Xextern int Reverse;
  176. Xextern Display *dpy;
  177. Xextern int scr;
  178. X
  179. Xstatic XContext Menu_context;
  180. Xstatic XContext Item_context;
  181. Xstatic contexts_created = FALSE;
  182. X
  183. XMenuItem *AddMenuItem(), *Display_Menu(), *MenuGetItem(),
  184. X     *MenuItemByName(), *MenuItemByData(), *GetInitialItem(), *MoveMenu();
  185. Xbool     DisposeItem(), SetItemCheck(), SetItemDisable(), Recalc_Menu(),
  186. X     SetupItems(), MapMenu(), SetItemText(), SetupMenuWindow();
  187. Xvoid     DisposeMenu(), InitMenu(), Undisplay_Menu(), MenuInvert(),
  188. X     PlacePointer(), Draw_Menu(), Draw_Item(),    SetInitialItem(),
  189. X     ClearInitialItem(), Generate_Menu_Entries(), UnmapMenu(),
  190. X     SetInputMask();
  191. XMenu     *NewMenu(), *MenuGetMenu();
  192. Xint     ItemGetMiddleY();
  193. X
  194. X/*
  195. X * AddMenuItem() adds a menu item to an existing menu, at the end of the
  196. X * list, which are number sequentially from zero.  The menuitem index is
  197. X * return, or -1 if failed.
  198. X */
  199. X
  200. XMenuItem *AddMenuItem(menu, text, bitmap_file)
  201. XMenu *menu;
  202. Xchar *text;
  203. Xchar *bitmap_file;
  204. X{
  205. X     MenuItem *menuitem, **next;
  206. X     int junk;
  207. X     char *data;
  208. X
  209. X     Entry("AddMenuItem")
  210. X
  211. X     if (!menu || (!text && !bitmap_file) || (menuitem = allocate(MenuItem, 1))
  212. X    == (MenuItem *)0)
  213. X      Leave(NULLITEM)
  214. X     bzero((char *)menuitem, sizeof(MenuItem));
  215. X     ItemText(menuitem) = allocate(char, (strlen(text) + 1));
  216. X     strcpy(ItemText(menuitem), text);
  217. X     ItemTextLength(menuitem) = strlen(text);
  218. X     if (bitmap_file) {
  219. X      bitmap_file = (char *)expand_from_path(bitmap_file);
  220. X      if (XReadBitmapFileData(bitmap_file,
  221. X                  &(menuitem->itemTextWidth),
  222. X                  &(menuitem->itemHeight),
  223. X                  &data,
  224. X                  &junk, &junk) != BitmapSuccess) {
  225. X           fprintf(stderr, "awm: Can't read bitmap file '%s'\n",
  226. X               bitmap_file);
  227. X           exit(1);
  228. X      }
  229. X      menuitem->itemBackground =
  230. X           XCreatePixmapFromBitmapData(dpy, RootWindow(dpy, scr),
  231. X                       data,
  232. X                       menuitem->itemTextWidth,
  233. X                       menuitem->itemHeight,
  234. X                       MForeground,
  235. X                       MBackground,
  236. X                       DefaultDepth(dpy, scr));
  237. X      if (!menuitem->itemBackground) {
  238. X           fprintf(stderr, "awm: Can't create pixmap for file '%s'\n",
  239. X               bitmap_file);
  240. X           exit(1);
  241. X      }
  242. X      free(data);
  243. X      free(bitmap_file);
  244. X     }
  245. X     for(next = &menu->menuItems; *next; next = &(*next)->nextItem);
  246. X
  247. X     *next = menuitem;
  248. X
  249. X     SetMenuFlag(menu, menuChanged);
  250. X     Leave(menuitem)
  251. X}
  252. X
  253. X/*
  254. X * DisposeItem() releases the memory allocated for the given indexed
  255. X * menuitem.  Nonzero is returned if an item was actual disposed of.
  256. X * It also checks to see whether the item we're disposing is the
  257. X * initial item for the menu -- if so, null out the initial item.
  258. X */
  259. Xbool DisposeItem(menu, item)
  260. XMenu *menu;
  261. XMenuItem *item;
  262. X{
  263. X     MenuItem **next, **last, *menuitem;
  264. X     Entry("DisposeItem")
  265. X
  266. X     if (MenuIsNull(menu) || ItemIsNull(item))
  267. X      Leave(FALSE)
  268. X     next = &MenuItems(menu);
  269. X     do {
  270. X      if(!*next)
  271. X           Leave(FALSE)
  272. X      last = next;
  273. X      next = &(*next)->nextItem;
  274. X     } while((*last != item) && !ItemIsNull(*next));
  275. X     menuitem = *last;
  276. X     *last = *next;
  277. X     if (ItemWindow(menuitem)) {
  278. X      XDeleteContext(dpy, ItemWindow(menuitem), Item_context);
  279. X      XDestroyWindow(dpy, ItemWindow(menuitem));
  280. X     }
  281. X     if (ItemIsInitialItem(menu, menuitem))
  282. X      ClearInitialItem(menu);
  283. X
  284. X     if (ItemText(menuitem))
  285. X      free((char*)ItemText(menuitem));
  286. X     free((char*)menuitem);
  287. X
  288. X     SetMenuFlag(menu, menuChanged);
  289. X     Leave(TRUE)
  290. X}
  291. X
  292. X/*
  293. X * DisposeMenu() releases the memory allocated for the given menu.
  294. X */
  295. Xvoid DisposeMenu(menu)
  296. XMenu *menu;
  297. X{
  298. X     Entry("DisposeMenu")
  299. X
  300. X     if(!menu)
  301. X      Leave_void
  302. X     if (TestMenuFlag(menu, menuMapped))
  303. X      UnmapMenu(menu);
  304. X     while(DisposeItem(menu, MenuItems(menu)));
  305. X     if(MenuWindow(menu)) {
  306. X      XDeleteContext(dpy, MenuWindow(menu), Menu_context);
  307. X      XDestroyWindow(dpy, MenuWindow(menu));
  308. X     }
  309. X     XFreePixmap (dpy, MenuGreyPixmap(menu));
  310. X     XFreePixmap (dpy, MenuArrowPixmap(menu));
  311. X     XFreePixmap (dpy, MenuCheckmarkPixmap(menu));
  312. X     XFreeGC (dpy, MenuNormalGC(menu));
  313. X     XFreeGC (dpy, MenuInvertGC(menu));
  314. X     XFreeGC (dpy, MenuHighlightedGC(menu));
  315. X     XFreeGC (dpy, menu->boldGC);
  316. X     
  317. X     if (MenuHasInitialItem(menu))
  318. X      ClearInitialItem(menu);
  319. X     free((char*) menu);
  320. X     Leave_void
  321. X}
  322. X
  323. Xstatic char *Name;
  324. X
  325. Xvoid InitMenu(name, options)
  326. Xchar *name;
  327. Xunsigned int options;
  328. X{
  329. X     char *cp;
  330. X     
  331. X     Entry("InitMenu")
  332. X
  333. X     Name = name;
  334. X     MenuDefault.menuFlags = menuChanged;
  335. X     
  336. X     MenuDefault.menuInitialItemText = (char *) NULL;
  337. X     MenuDefault.display = dpy;
  338. X     MenuDefault.screen = scr;
  339. X     MenuDefault.menuOptions = options;
  340. X     Leave_void
  341. X}
  342. X
  343. X/*
  344. X * ItemText changes the text of item of the menu.
  345. X */
  346. Xbool SetItemText(menu, item, text)
  347. XMenu *menu;
  348. XMenuItem *item;
  349. Xchar *text;
  350. X{
  351. X     Entry("SetItemText")
  352. X
  353. X     if (strcmp (ItemText(item), text) == 0)
  354. X      Leave (True)
  355. X     
  356. X     if(ItemText(item))
  357. X      free((char *) ItemText(item));
  358. X     
  359. X     ItemText(item) = allocate(char, (strlen(text) + 1));
  360. X     strcpy(ItemText(item), text);
  361. X     
  362. X     ItemTextLength(item) = strlen (text);
  363. X     SetMenuFlag(menu, menuChanged);
  364. X     
  365. X     (void) Recalc_Menu (menu);
  366. X     Leave(TRUE)
  367. X}
  368. X
  369. X/*
  370. X * NewMenu() returns a pointer to an initialized new Menu structure, or NULL
  371. X * if failed.
  372. X *
  373. X * The Menu structure _menuDefault contains the default menu settings.
  374. X */
  375. XMenu *NewMenu()
  376. X{
  377. X     extern Pixmap MakeGreyStipple ();
  378. X     Menu *menu = 0;
  379. X     
  380. X     XGCValues gcValues, invertGCValues;
  381. X     
  382. X     static unsigned long gcMask =
  383. X      GCFunction | GCForeground | GCBackground | GCFont | GCStipple;
  384. X     static unsigned long invertgcMask = GCFont | GCFunction;
  385. X     char *cp;
  386. X
  387. X     Entry("NewMenu")
  388. X
  389. X     /*
  390. X      * Allocate the memory for the menu structure.
  391. X      */
  392. X     if(MenuIsNull((menu = allocate(Menu, 1))))
  393. X      Leave(NULLMENU)
  394. X     
  395. X     /*
  396. X      * Initialize to default values.
  397. X      */
  398. X     *menu = MenuDefault;
  399. X     gcValues.font = MFontInfo->fid;
  400. X     
  401. X     /*
  402. X      * If the menu cursor hasn't been given, make a default one.
  403. X      */
  404. X
  405. X     MenuCursor(menu) = XCreateFontCursor (dpy, XC_right_ptr);
  406. X     MenuArrowPixmap(menu) = XCreatePixmapFromBitmapData(dpy,
  407. X                             RootWindow(dpy, scr),
  408. X                             arrow_bits,
  409. X                             arrow_width,
  410. X                             arrow_height,
  411. X                             MForeground,
  412. X                             MBackground,
  413. X                             DefaultDepth(dpy, scr));
  414. X
  415. X     MenuGreyPixmap(menu) = XCreateBitmapFromData(dpy,
  416. X                          RootWindow(dpy, scr),
  417. X                          gray1_bits,
  418. X                          gray1_width, gray1_height);
  419. X     
  420. X     MenuCheckmarkPixmap(menu) = XCreatePixmapFromBitmapData(dpy,
  421. X                                 RootWindow(dpy, scr),
  422. X                                 Check_MarkBits,
  423. X                                 checkMarkWidth,
  424. X                                 checkMarkHeight,
  425. X                                 MForeground,
  426. X                                 MBackground,
  427. X                                 DefaultDepth(dpy, scr));
  428. X
  429. X     gcValues.foreground = MForeground;
  430. X     gcValues.background = MBackground;
  431. X
  432. X     gcValues.stipple = MenuGreyPixmap(menu);
  433. X     gcValues.function = GXcopy;
  434. X     gcValues.subwindow_mode = IncludeInferiors;
  435. X     gcValues.graphics_exposures = False;
  436. X     MenuNormalGC(menu) =
  437. X      XCreateGC (dpy, RootWindow(dpy, scr),
  438. X             gcMask | GCSubwindowMode | GCGraphicsExposures,  &gcValues);
  439. X     
  440. X     invertGCValues = gcValues;
  441. X     invertGCValues.foreground = MBackground;
  442. X     invertGCValues.background = MForeground;
  443. X     MenuHighlightedGC(menu) = XCreateGC (dpy, RootWindow (dpy, scr),
  444. X                      gcMask, &invertGCValues);
  445. X     gcValues.function = GXinvert;
  446. X     MenuInvertGC(menu) = XCreateGC (dpy, RootWindow (dpy, scr),
  447. X                     invertgcMask, &gcValues);
  448. X     gcValues.function = GXcopy;
  449. X     gcValues.font = MBoldFontInfo->fid;
  450. X     menu->boldGC = XCreateGC(dpy, RootWindow(dpy, scr),
  451. X            gcMask | GCSubwindowMode | GCGraphicsExposures,  &gcValues);
  452. X     Leave(menu)
  453. X}
  454. X
  455. X
  456. X/*
  457. X * SetItemCheck sets the check state of item of the menu to "state".
  458. X */
  459. Xbool SetItemCheck(menu, item, state)
  460. XMenu *menu;
  461. XMenuItem *item;
  462. Xint state;
  463. X{
  464. X     Entry("SetItemCheck")
  465. X
  466. X     if (TestItemFlag(item,itemChecked) == state) /* Exit if unchanged */
  467. X      Leave (True)
  468. X     
  469. X     if (state)
  470. X      SetItemFlag(item, itemChecked);
  471. X     else
  472. X      ResetItemFlag(item, itemChecked);
  473. X     
  474. X     SetItemFlag(item, itemChanged);
  475. X     SetMenuFlag(menu, menuItemChanged);
  476. X     
  477. X     Leave(TRUE)
  478. X}
  479. X/*
  480. X * SetItemDeaf sets the "deaf" state of item of the menu to "state".
  481. X * "deaf" means that the item is display only and not sensitive to input.
  482. X */
  483. Xbool SetItemDeaf(menu, item, state)
  484. XMenu *menu;
  485. XMenuItem *item;
  486. Xint state;
  487. X{
  488. X     Entry("SetItemDeaf")
  489. X
  490. X     if (TestItemFlag(item,itemDeaf) == state) /* Exit if unchanged */
  491. X      Leave (True)
  492. X     
  493. X     if (state)
  494. X      SetItemFlag(item, itemDeaf);
  495. X     else
  496. X      ResetItemFlag(item, itemDeaf);
  497. X     
  498. X     SetItemFlag(item, itemChanged);
  499. X     SetMenuFlag(menu, menuItemChanged);
  500. X     if (ItemIsInitialItem(menu, item))
  501. X      ClearInitialItem(menu);
  502. X     Leave(TRUE)
  503. X}
  504. X
  505. X/*
  506. X * SetItemDisable sets the disable state of item "n" of the menu to "state".
  507. X */
  508. Xbool SetItemDisable(menu, item, state)
  509. XMenu *menu;
  510. XMenuItem *item;
  511. Xint state;
  512. X{
  513. X     Entry("SetItemDisable")
  514. X
  515. X     if (TestItemFlag(item,itemDisabled) == state) /* Exit if unchanged */
  516. X      Leave (True)
  517. X     
  518. X     if(state)
  519. X     {
  520. X      SetItemFlag(item, itemDisabled);
  521. X      /* if disabled item is currently initial item, null initial item */
  522. X      if (ItemIsInitialItem(menu, item))
  523. X           ClearInitialItem(menu);
  524. X     }
  525. X     else
  526. X      ResetItemFlag(item, itemDisabled);
  527. X     
  528. X     SetItemFlag(item, itemChanged);
  529. X     SetMenuFlag(menu, menuItemChanged);
  530. X     
  531. X     Leave(TRUE)
  532. X}
  533. X
  534. XMenuItem *Display_Menu(menu, parent, x, y)
  535. XMenu *menu;
  536. XMenu *parent;
  537. Xint x;
  538. Xint y;
  539. X{
  540. X     MenuItem *item;
  541. X     
  542. X     Entry("Display_Menu")
  543. X
  544. X     if (MenuIsNull(menu))
  545. X      Leave(FALSE)
  546. X     
  547. X     MenuParent(menu) = parent;
  548. X     
  549. X     if (MenuIsNull(parent))
  550. X      MenuNested(menu) = 0;
  551. X     else
  552. X      MenuNested(menu) = MenuNested(parent) + 1;
  553. X     if (!MenuWindow(menu) || TestMenuFlag(menu,
  554. X        (menuChanged | menuItemChanged))) {
  555. X      if (!SetupMenuWindow(menu))
  556. X           Leave(NULL)
  557. X      Generate_Menu_Entries(menu);
  558. X     }
  559. X     if (TestOptionFlag(menu,savebits) &&
  560. X     (MenuSavedPixmap(menu) != (Pixmap) 0))
  561. X      SetInputMask(menu, MenuIgnoreMask);
  562. X     else
  563. X      SetInputMask(menu, ExposureMask);
  564. X     if (!(item = MoveMenu(menu, x, y)) || !MapMenu(menu))
  565. X      Leave(FALSE)
  566. X     Draw_Menu(menu);
  567. X     
  568. X     Leave(item)
  569. X}
  570. X
  571. Xvoid Undisplay_Menu(menu)
  572. XMenu *menu;
  573. X{
  574. X     Entry("Undisplay_Menu")
  575. X
  576. X     if (MenuIsNull(menu))
  577. X      Leave_void
  578. X     
  579. X     MenuParent(menu) = NULLMENU;
  580. X     MenuNested(menu) = 0;
  581. X     
  582. X     UnmapMenu(menu);
  583. X     Leave_void
  584. X}
  585. X
  586. Xvoid MenuInvert(menu, item)
  587. XMenu *menu;
  588. XMenuItem *item;
  589. X{
  590. X     Entry("MenuInvert")
  591. X
  592. X     XFillRectangle (dpy,
  593. X             ItemWindow(item),
  594. X             MenuInvertGC(menu),
  595. X             0, 0, 
  596. X             MenuWidth(menu),
  597. X             item->itemHeight);
  598. X     Leave_void
  599. X}
  600. X
  601. X/*
  602. X * Recalculate all of the various menu and item variables.
  603. X */
  604. Xbool Recalc_Menu(menu)
  605. XMenu *menu;
  606. X{
  607. X     MenuItem *item;
  608. X     int max, height, fontheight, boldfontheight, nitems;
  609. X     /* Gets set to false first time we see an item with text */
  610. X     unsigned int menuIsPictures = TRUE;
  611. X     
  612. X     Entry("Recalc_Menu")
  613. X
  614. X     /*
  615. X      * We must have already gotten the menu font.
  616. X      */
  617. X     if(!MFontInfo)
  618. X      Leave(FALSE)
  619. X     /*
  620. X      * Initialize the various max width variables.
  621. X      */
  622. X     fontheight = MFontInfo->ascent + MFontInfo->descent + 2;
  623. X     boldfontheight = MBoldFontInfo->ascent + MBoldFontInfo->descent + 2;
  624. X     height = nitems = 0;
  625. X     MenuMaxTextWidth(menu) = 0;
  626. X     /*
  627. X      * The item height is the maximum of the font height and the
  628. X      * checkbox height, unless we find out that it's a pixmap (in which
  629. X      * case, most of these values are overridden).
  630. X      */
  631. X     max = fontheight;
  632. X     if(checkMarkHeight > max)
  633. X      max = checkMarkHeight;
  634. X     
  635. X     max += 2*MItemBorder;
  636. X     max = MakeEven(max);
  637. X             
  638. X     /*
  639. X      * Go through the menu item list.
  640. X      */
  641. X     for(item = MenuItems(menu) ; item ; item = ItemNext(item)) {
  642. X      if (item->itemBackground)    /* pixmap is static size */
  643. X           max = item->itemHeight;
  644. X      else {
  645. X           if (ItemIsDeaf(item))    /* It's a label, use bold info */
  646. X            max = boldfontheight;
  647. X           else
  648. X            max = fontheight;
  649. X      }
  650. X      if (checkMarkHeight > max)
  651. X           max = checkMarkHeight;
  652. X      if (!item->itemBackground) {
  653. X           max += 2 * MItemBorder;
  654. X           max = MakeEven(max);
  655. X           item->itemHeight = max;
  656. X      }
  657. X      height += max;
  658. X      nitems++;
  659. X      /*
  660. X       * Check the text width with the max value stored in
  661. X       * menu.
  662. X       */
  663. X      if (!item->itemBackground) {
  664. X           if ((ItemTextWidth(item) = XTextWidth(ItemIsDeaf(item) ?
  665. X                             MBoldFontInfo
  666. X                             : MFontInfo,
  667. X                             ItemText(item),
  668. X                             strlen (ItemText(item))))
  669. X                  > MenuMaxTextWidth(menu))
  670. X                    MenuMaxTextWidth(menu) = ItemTextWidth(item);
  671. X           menuIsPictures = FALSE;
  672. X          }
  673. X          /* ItemTextWidth is really pixmap size. Yick. */
  674. X      else {
  675. X               if (ItemTextWidth(item) > MenuMaxTextWidth(menu))
  676. X                    MenuMaxTextWidth(menu) = ItemTextWidth(item);
  677. X          }
  678. X
  679. X     }
  680. X     /*
  681. X      * Set the menu height and then set the menu width.
  682. X      */
  683. X     MenuHeight(menu) = height;
  684. X     menu->avgHeight = height / nitems;
  685. X
  686. X     if (menuIsPictures == TRUE)
  687. X      MenuWidth(menu) = MenuMaxTextWidth(menu) + (2 * MItemBorder);
  688. X     else {
  689. X      MenuWidth(menu) = 4 * MenuItemPad(menu) + MenuMaxTextWidth(menu) +
  690. X           checkMarkWidth + arrow_width + (2 * MItemBorder);
  691. X     }
  692. X     MenuItemWidth(menu) = MenuWidth(menu) - (2 * MItemBorder);
  693. X     Leave(TRUE)
  694. X}
  695. X
  696. X/*
  697. X * Figure out where to popup the menu, relative to the where the button was
  698. X * pressed.
  699. X * Returns pointer to initial item to warp to.
  700. X */
  701. Xstatic MenuItem *MoveMenu(menu, ev_x, ev_y)
  702. XMenu *menu;
  703. Xint ev_x, ev_y;
  704. X{
  705. X     int x, y;
  706. X     int total_width, total_height;
  707. X     int offset;
  708. X     MenuItem *item;
  709. X     Window junk;
  710. X     int r_x, foo, state;
  711. X     
  712. X     Entry("MoveMenu")
  713. X
  714. X     /*
  715. X      * Get the coordinates of the mouse when the button was pressed.
  716. X      */
  717. X     
  718. X     total_width = MenuWidth(menu) + 2 * MenuBorderWidth(menu);
  719. X     total_height = MenuHeight(menu) + 2 * MenuBorderWidth(menu);
  720. X
  721. X     XQueryPointer(dpy, RootWindow(dpy, scr), &junk, &junk, &r_x, &y,
  722. X           &foo, &foo, &state); 
  723. X     x = ev_x - MenuItemPad(menu);
  724. X     if (x < 0)
  725. X      x = 0;
  726. X     else if (TestOptionFlag(menu, rightoffset) &&
  727. X          !MenuIsNull(MenuParent(menu)))
  728. X     {
  729. X      /* check whether parent is close to right edge... */
  730. X      /* "too close" means that child would leave < delta of its parent */
  731. X      /* visible to its left.                                           */
  732. X      if (TestOptionFlag(menu, bigoffset))
  733. X      {
  734. X           if (MenuX(MenuParent(menu)) + MenuWidth(MenuParent(menu)) > 
  735. X           DisplayWidth(dpy, scr) - total_width)
  736. X            x = MenuX(MenuParent(menu))
  737. X             - total_width + 2*MenuBorderWidth(menu);
  738. X      }
  739. X      else
  740. X      {
  741. X           if (MenuX(MenuParent(menu)) + MenuDelta(MenuParent(menu)) > 
  742. X           DisplayWidth(dpy, scr) - total_width)
  743. X           {
  744. X            x = (MenuX(MenuParent(menu)) + MenuWidth(MenuParent(menu)) +
  745. X             2 * MenuBorderWidth(MenuParent(menu))
  746. X             - total_width - MenuDelta(menu));
  747. X           }
  748. X      }
  749. X     }
  750. X     if (x + total_width >
  751. X     DisplayWidth(dpy, scr))
  752. X      x = DisplayWidth(dpy, scr)
  753. X           - total_width;
  754. X     
  755. X     /*
  756. X      * If we have an initial item, try to popup the menu centered
  757. X      * vertically within this item.
  758. X      */
  759. X     if(MenuHasInitialItem(menu)) {
  760. X      int tmp_y;
  761. X
  762. X      /*
  763. X       * Look through the item list. "y" is the vertical position
  764. X       * of the top of the current item and "n" is the item number.
  765. X       */
  766. X      offset = MenuBorderWidth(menu);
  767. X      for(item = MenuItems(menu) ; ;) {
  768. X           /*
  769. X        * On finding the initial item, center within this item.
  770. X        */
  771. X           if (ItemIsInitialItem(menu, item)) {
  772. X            y -= offset;
  773. X            break;
  774. X           }
  775. X           else
  776. X            offset += item->itemHeight;
  777. X           /*
  778. X        * If we run out of items, turn off the initial item
  779. X        * and treat this as if no initial item.
  780. X        */
  781. X           if(!(item = ItemNext(item))) {
  782. X            ClearInitialItem(menu);
  783. X            break;
  784. X           }
  785. X      }
  786. X     }
  787. X     
  788. X     if (y < 0)
  789. X      y = 0;
  790. X     else if (y + total_height >
  791. X          DisplayHeight(dpy, scr))
  792. X     {
  793. X      y = DisplayHeight(dpy, scr)
  794. X           - (total_height + 1);
  795. X     }
  796. X     y = MakeEven(y) + 1;
  797. X     XMoveWindow(dpy, MenuWindow(menu), x, y);
  798. X     MenuX(menu) = x;
  799. X     MenuY(menu) = y;
  800. X     
  801. X     if (!ItemIsInitialItem(menu, item))
  802. X      item = MenuItems(menu);
  803. X     Leave(item)
  804. X}
  805. X
  806. X
  807. Xvoid PlacePointer(menu, item)
  808. XMenu *menu;
  809. XMenuItem *item;
  810. X{
  811. X     int y;
  812. X     
  813. X     Entry("PlacePointer")
  814. X
  815. X     y = ItemGetMiddleY(item);
  816. X     
  817. X     XWarpPointer(dpy, None,
  818. X          RootWindow(dpy, scr), 
  819. X          0, 0, 0, 0, 
  820. X          MenuX(menu) + MPad + (MenuWidth(menu) / 2), y);
  821. X     Leave_void
  822. X}
  823. X
  824. X/*
  825. X * Map the menu window.
  826. X */
  827. Xstatic bool MapMenu(menu)
  828. XMenu *menu;
  829. X{
  830. X     Entry("MapMenu")
  831. X
  832. X     if (!TestMenuFlag(menu, menuMapped))
  833. X      MenuItemHighlighted(menu) = NULLITEM;
  834. X     
  835. X     /*
  836. X      * Actually map the window.
  837. X      */
  838. X     
  839. X     if (TestOptionFlag(menu,savebits))
  840. X     {
  841. X      if ((MenuSavedPixmap(menu) == (Pixmap) 0) ||
  842. X          (MenuOldWidth(menu) != MenuWidth(menu)) ||
  843. X          (MenuOldHeight(menu) != MenuHeight(menu)) ||
  844. X          (MenuOldBorderWidth(menu) != MenuBorderWidth(menu)))
  845. X      {
  846. X           if (MenuSavedPixmap(menu) != (Pixmap) 0)
  847. X            XFreePixmap(dpy, MenuSavedPixmap(menu));
  848. X           
  849. X           MenuSavedPixmap(menu) =
  850. X            XCreatePixmap(dpy, 
  851. X                  RootWindow(dpy, scr), 
  852. X                  MenuWidth(menu) + 2*MenuBorderWidth(menu),
  853. X                  MenuHeight(menu) + 2*MenuBorderWidth(menu),
  854. X                  DefaultDepth(dpy, scr));
  855. X           DBUG_5("Pixmaps","Created pixmap: width %d, height %d, depth %d\n",
  856. X              MenuWidth(menu) + 2*MenuBorderWidth(menu),
  857. X              MenuHeight(menu) + 2*MenuBorderWidth(menu),
  858. X              DefaultDepth(dpy, scr)); 
  859. X           MenuOldWidth(menu) = MenuWidth(menu);
  860. X           MenuOldHeight(menu) = MenuHeight(menu);
  861. X           MenuOldBorderWidth(menu) = MenuBorderWidth(menu);
  862. X      }
  863. X      else
  864. X           SetInputMask(menu, ExposureMask);
  865. X      
  866. X      if (MenuSavedPixmap(menu) != (Pixmap) 0) { 
  867. X           /*    XFillRectangle(dpy,
  868. X            MenuSavedPixmap(menu),
  869. X            SaveGC,
  870. X            0,0,
  871. X            MenuWidth(menu) + 2*MenuBorderWidth(menu),
  872. X            MenuHeight(menu) + 2*MenuBorderWidth(menu)); */
  873. X           SetInputMask(menu, MenuIgnoreMask);
  874. X           XCopyArea(dpy, 
  875. X             RootWindow(dpy, scr),
  876. X             MenuSavedPixmap(menu),
  877. X             MenuNormalGC(menu),
  878. X             MenuX(menu), 
  879. X             MenuY(menu), 
  880. X             (unsigned int) (MenuWidth(menu) + 2*MenuBorderWidth(menu)), 
  881. X             (unsigned int) (MenuHeight(menu) + 2*MenuBorderWidth(menu)), 
  882. X             0, 0);
  883. X      }
  884. X      else
  885. X           SetInputMask(menu, ExposureMask);
  886. X      
  887. X     }
  888. X     
  889. X     XRaiseWindow(dpy, MenuWindow(menu));
  890. X     XMapWindow(dpy, MenuWindow(menu));
  891. X     SetMenuFlag(menu, menuMapped);
  892. X     Leave(TRUE)
  893. X}
  894. X
  895. Xstatic void Generate_Menu_Entries (menu)
  896. XMenu *menu;
  897. X{
  898. X     MenuItem *item;
  899. X     
  900. X     Entry("Generate_Menu_Entries")
  901. X
  902. X     for (item = MenuItems(menu); item; (item = ItemNext(item))) {
  903. X      
  904. X      if (ItemGenerator(item)) {
  905. X           char *newText;
  906. X           
  907. X           (ItemGenerator(item)) (&newText, &ItemCallback(item));
  908. X           SetItemText (menu, item, newText);
  909. X      }
  910. X      
  911. X      if (ItemCheckproc(item))
  912. X           SetItemCheck (menu, item, (ItemCheckproc(item))(menu,item));
  913. X     }
  914. X     Leave_void
  915. X}
  916. X
  917. X/*
  918. X * Draw the entire menu in the blank window.
  919. X */
  920. Xvoid Draw_Menu(menu)
  921. XMenu *menu;
  922. X{
  923. X     MenuItem *item;
  924. X     
  925. X     Entry("Draw_Menu")
  926. X
  927. X     ResetMenuFlag(menu, menuChanged);
  928. X     /*
  929. X      * For each item in the list, first draw any check mark and then
  930. X      * draw the rest of it.
  931. X      */
  932. X     for(item = MenuItems(menu) ; item ; item = ItemNext(item)) {
  933. X      if (TestOptionFlag(menu, savebits))
  934. X      {
  935. X           /* go ahead and draw it, don't wait for exposes */
  936. X           Draw_Item(menu, item, 0, 0, MenuWidth(menu), item->itemHeight);
  937. X      }
  938. X     }
  939. X     Leave_void
  940. X}
  941. X
  942. X/*
  943. X * Draw the item  at vertical position y.
  944. X */
  945. Xvoid Draw_Item(menu, item, fill_x, fill_y, fill_width, fill_height)
  946. XMenu *menu;
  947. XMenuItem *item;
  948. Xint fill_x, fill_y, fill_width, fill_height;
  949. X{
  950. X     int y;  /* baseline */
  951. X     int x = MenuItemPad(menu);
  952. X     int x1 = 2 * MenuItemPad(menu) + checkMarkWidth;
  953. X     int pad;
  954. X     int high;
  955. X     XGCValues gcValues;
  956. X     
  957. X     Entry("Draw_Item")
  958. X
  959. X     if (TestItemFlag(item, itemDisabled))
  960. X     {
  961. X      gcValues.fill_style = FillOpaqueStippled;
  962. X      XChangeGC(dpy, MenuNormalGC(menu),
  963. X            (GCFillStyle), &gcValues);
  964. X     }
  965. X     
  966. X     high = (MenuItemHighlighted(menu) == item);
  967. X     if (!item->itemBackground) {
  968. X      if (high && !TestItemFlag(item, itemDeaf))
  969. X      {
  970. X           XSetFunction(dpy, MenuNormalGC(menu), GXset);
  971. X           XFillRectangle(dpy, ItemWindow(item),
  972. X                  MenuNormalGC(menu), fill_x, fill_y,
  973. X                  fill_width, fill_height);
  974. X           XSetFunction(dpy, MenuNormalGC(menu), GXcopyInverted);
  975. X      }
  976. X      else
  977. X           XClearArea(dpy, ItemWindow(item),
  978. X              fill_x, fill_y, fill_width, fill_height, False);
  979. X      
  980. X      /*
  981. X       * Draw the check mark, possibly dimmed, wherever is necessary.
  982. X       */
  983. X     }
  984. X     if(TestItemFlag(item, itemChecked)){
  985. X      XCopyArea (dpy, MenuCheckmarkPixmap(menu),
  986. X             ItemWindow(item),
  987. X             MenuNormalGC(menu),
  988. X             0, 0, checkMarkWidth, checkMarkHeight,
  989. X             (int) x, (item->itemHeight - checkMarkHeight) / 2);
  990. X     }
  991. X     /* Draw submenu indicator arrow */
  992. X     if(ItemSubmenu(item)) {
  993. X      XCopyArea (dpy, MenuArrowPixmap(menu),
  994. X             ItemWindow(item),
  995. X             MenuNormalGC(menu),
  996. X             0, 0,
  997. X             arrow_width, arrow_height,
  998. X             (int) (x + MenuItemWidth(menu) -
  999. X                arrow_width - MenuItemPad(menu)),
  1000. X             (item->itemHeight - arrow_height) / 2 - 1);
  1001. X     }
  1002. X     /*
  1003. X      * Draw the text, centered vertically.
  1004. X      */
  1005. X     if (!item->itemBackground) {
  1006. X      if (!TestItemFlag(item, itemDeaf)) {
  1007. X           pad = (item->itemHeight - 
  1008. X              (MFontInfo->ascent + MFontInfo->descent)) / 2;
  1009. X           y = item->itemHeight - pad - MFontInfo->descent;
  1010. X           
  1011. X           XDrawString (dpy, ItemWindow(item), 
  1012. X                (high? MenuHighlightedGC(menu) : MenuNormalGC(menu)),
  1013. X                x1, y, ItemText(item), ItemTextLength(item));
  1014. X           if (high)
  1015. X            XSetFunction(dpy, MenuNormalGC(menu), GXcopy);
  1016. X           if (TestItemFlag(item, itemDisabled))
  1017. X           { 
  1018. X            gcValues.fill_style = FillSolid;
  1019. X            XChangeGC(dpy, MenuNormalGC(menu),
  1020. X                  (GCFillStyle), &gcValues);
  1021. X           }
  1022. X           
  1023. X      }
  1024. X      else {
  1025. X           pad = (item->itemHeight - (MBoldFontInfo->ascent +
  1026. X                      MBoldFontInfo->descent)) / 2;
  1027. X           y = item->itemHeight - pad - MBoldFontInfo->descent;
  1028. X           XDrawString(dpy, ItemWindow(item), menu->boldGC, x1, y,
  1029. X               ItemText(item), ItemTextLength(item));
  1030. X      }
  1031. X     }
  1032. X     Leave_void
  1033. X}
  1034. X
  1035. X
  1036. X/*
  1037. X * UnmapMenu() unmaps a menu, if it is currently mapped.
  1038. X */
  1039. Xstatic void UnmapMenu(menu)
  1040. XMenu *menu;
  1041. X{
  1042. X     Entry("UnmapMenu")
  1043. X
  1044. X     if(!menu || !(TestMenuFlag(menu, menuMapped)))
  1045. X      Leave_void
  1046. X     XUnmapWindow(dpy, MenuWindow(menu));
  1047. X     /*    XClearWindow (dpy, MenuWindow(menu));*/
  1048. X     
  1049. X     if (TestOptionFlag(menu, savebits))
  1050. X     {
  1051. X      if (MenuSavedPixmap(menu))
  1052. X           XCopyArea (dpy,
  1053. X              MenuSavedPixmap(menu),
  1054. X              RootWindow (dpy, scr),
  1055. X              MenuNormalGC(menu),
  1056. X              0, 0, 
  1057. X              MenuWidth(menu) + 2*MenuBorderWidth(menu),
  1058. X              MenuHeight(menu) + 2*MenuBorderWidth(menu),
  1059. X              MenuX(menu), MenuY(menu));
  1060. X      
  1061. X     }
  1062. X     ResetMenuFlag(menu, menuMapped);
  1063. X     Leave_void
  1064. X}
  1065. X
  1066. Xstatic bool SetupMenuWindow (menu)
  1067. XMenu *menu;
  1068. X{
  1069. X     int changed = TestMenuFlag(menu, (menuChanged | menuItemChanged));
  1070. X     Entry("SetupMenuWindow")
  1071. X
  1072. X     if (contexts_created == FALSE) {
  1073. X      contexts_created = TRUE;
  1074. X      Menu_context = XUniqueContext(); 
  1075. X      Item_context = XUniqueContext();
  1076. X     }
  1077. X     
  1078. X     /*
  1079. X      * If the entire menu has changed, throw away any saved pixmap and
  1080. X      * then call RecalcMenu().
  1081. X      */
  1082. X     
  1083. X     if(changed & menuChanged) {
  1084. X      if(!Recalc_Menu(menu))
  1085. X           Leave(FALSE)
  1086. X      changed &= ~menuItemChanged;
  1087. X     }
  1088. X     
  1089. X     if(!MenuWindow(menu)) {
  1090. X      static unsigned long valuemask =
  1091. X           CWOverrideRedirect | CWBorderPixel | CWBackPixel;
  1092. X      XSetWindowAttributes attributes;
  1093. X      
  1094. X      attributes.override_redirect = True;
  1095. X      attributes.border_pixel = MBorder;
  1096. X      attributes.background_pixel = MBackground;
  1097. X      if (SaveUnder) {
  1098. X           attributes.save_under = True;
  1099. X           valuemask |= CWSaveUnder;
  1100. X      }
  1101. X
  1102. X      if((MenuWindow(menu) =
  1103. X          XCreateWindow(dpy, 
  1104. X                RootWindow(dpy, scr),
  1105. X                0, 0,
  1106. X                MenuWidth(menu), MenuHeight(menu),
  1107. X                MenuBorderWidth(menu),
  1108. X                DefaultDepth(dpy, scr),
  1109. X                InputOutput, 
  1110. X                DefaultVisual(dpy, scr),
  1111. X                valuemask, &attributes)
  1112. X          ) == (Window)0)
  1113. X           Leave(FALSE)
  1114. X      else if (SetupItems(menu) == FALSE)
  1115. X           Leave(FALSE)
  1116. X
  1117. X      XSaveContext(dpy, MenuWindow(menu), Menu_context, (char *) menu);
  1118. X      XMapSubwindows(dpy, MenuWindow(menu));
  1119. X      
  1120. X      XDefineCursor(dpy, MenuWindow(menu), MenuCursor(menu));
  1121. X     }
  1122. X     else if(changed & menuChanged) {
  1123. X      XResizeWindow(dpy, MenuWindow(menu),
  1124. X            MenuWidth(menu), MenuHeight(menu));
  1125. X      if (SetupItems(menu) == FALSE)
  1126. X           Leave(FALSE)
  1127. X      XMapSubwindows(dpy, MenuWindow(menu));
  1128. X     }
  1129. X     Leave(TRUE)
  1130. X}
  1131. X
  1132. Xstatic bool SetupItems(menu)
  1133. XMenu *menu;
  1134. X{
  1135. X     int y;
  1136. X     MenuItem *item;
  1137. X     int changed = TestMenuFlag(menu, (menuChanged | menuItemChanged));
  1138. X
  1139. X     Entry("SetupItems")
  1140. X     
  1141. X     for (item = MenuItems(menu), y = 0; item;
  1142. X      y += item->itemHeight, item = ItemNext(item)) {
  1143. X      if (!ItemWindow(item)) {
  1144. X           static unsigned long valuemask =
  1145. X            (CWOverrideRedirect | CWBorderPixel | CWBackPixel);
  1146. X           XSetWindowAttributes attributes;
  1147. X
  1148. X           attributes.override_redirect = True;
  1149. X           attributes.border_pixel = MBorder;
  1150. X           attributes.background_pixel = MBackground;
  1151. X
  1152. X           if((ItemWindow(item) =
  1153. X           XCreateWindow(dpy, 
  1154. X                 MenuWindow(menu),
  1155. X                 0, y, 
  1156. X                 MenuItemWidth(menu), 
  1157. X                 item->itemHeight - (2 * MItemBorder), 
  1158. X                 MItemBorder,
  1159. X                 DefaultDepth(dpy, scr),
  1160. X                 InputOutput, 
  1161. X                 DefaultVisual(dpy, scr),
  1162. X                 valuemask, &attributes)
  1163. X           ) == (Window) 0)
  1164. X            Leave(FALSE)
  1165. X           if (item->itemBackground) {
  1166. X            XSetWindowBackgroundPixmap(dpy, ItemWindow(item),
  1167. X                           item->itemBackground);
  1168. X            XFreePixmap(dpy, item->itemBackground);
  1169. X           }
  1170. X           ItemMenu(item) = menu;
  1171. X           XSaveContext(dpy, ItemWindow(item), Item_context,
  1172. X                (char *) item);
  1173. X           XDefineCursor(dpy, ItemWindow(item),
  1174. X                 MenuCursor(menu));
  1175. X      }
  1176. X      
  1177. X      else if (changed & menuChanged) {
  1178. X           XResizeWindow(dpy, ItemWindow(item),
  1179. X                 MenuItemWidth(menu), 
  1180. X                 item->itemHeight - (2 * MItemBorder));
  1181. X           XMoveWindow(dpy, ItemWindow(item), 0, y);
  1182. X      }
  1183. X     }
  1184. X     Leave(TRUE)
  1185. X}
  1186. X
  1187. Xstatic void SetInputMask(menu, mask)
  1188. XMenu *menu;
  1189. Xunsigned int mask;
  1190. X{
  1191. X     MenuItem *item;
  1192. X     Entry("SetInputMask")
  1193. X
  1194. X     XSelectInput(dpy, MenuWindow(menu),
  1195. X          (mask | MenuEventMask));
  1196. X     for(item = MenuItems(menu) ; item ; item = ItemNext(item))
  1197. X     {
  1198. X      if (TestItemFlag(item, itemDisabled) || TestItemFlag(item, itemDeaf))
  1199. X           XSelectInput(dpy, ItemWindow(item),
  1200. X                (mask | MenuIgnoreMask));
  1201. X      else if (ItemIsLeaf(item))
  1202. X           XSelectInput(dpy, ItemWindow(item),
  1203. X                (mask | NormalItemEventMask));
  1204. X      else
  1205. X           XSelectInput(dpy, ItemWindow(item),
  1206. X                (mask | SubmenuItemEventMask));
  1207. X     }
  1208. X     Leave_void
  1209. X}
  1210. X
  1211. XMenuItem *MenuItemByData(menu, data)
  1212. XMenu* menu;
  1213. Xpointer data;
  1214. X{
  1215. X     MenuItem *item;
  1216. X     
  1217. X     Entry("MenuItemByData")
  1218. X
  1219. X     for (item = MenuItems(menu);
  1220. X      !ItemIsNull(item) && (ItemData(item) != data);
  1221. X      item = ItemNext(item));
  1222. X     
  1223. X     Leave(item)
  1224. X}   
  1225. X
  1226. XMenuItem *MenuItemByName (menu, name)
  1227. XMenu *menu;
  1228. Xchar *name;
  1229. X{
  1230. X     MenuItem *item;
  1231. X
  1232. X     Entry("MenuItemByName")
  1233. X
  1234. X     for (item = MenuItems(menu); item; item = ItemNext(item))
  1235. X      if (strcmp (name, ItemText(item)) == 0)
  1236. X           Leave(item)
  1237. X     Leave(NULLITEM)
  1238. X}
  1239. X
  1240. XMenuItem *MenuGetItem(menu, window) 
  1241. XMenu *menu;
  1242. XWindow window;
  1243. X{    
  1244. X     MenuItem *foo = 0;
  1245. X     Entry("MenuGetItem")
  1246. X
  1247. X     XFindContext(dpy, window, Item_context, &foo);
  1248. X     Leave(foo)
  1249. X}
  1250. X
  1251. XMenu *MenuGetMenu(menu, window)
  1252. XMenu *menu;
  1253. XWindow window;
  1254. X{
  1255. X     Menu *bar = 0;
  1256. X     Entry("MenuGetMenu")
  1257. X
  1258. X     XFindContext(dpy, window, Menu_context, &bar);
  1259. X     Leave(bar)
  1260. X}
  1261. X
  1262. Xint ItemGetMiddleY(item)
  1263. XMenuItem *item;
  1264. X{
  1265. X     Window child;
  1266. X     XWindowAttributes attributes;
  1267. X     int x, y;
  1268. X     Entry("ItemGetMiddleY")
  1269. X
  1270. X     XGetWindowAttributes(dpy, ItemWindow(item), &attributes);
  1271. X     XTranslateCoordinates(dpy,
  1272. X               MenuWindow(ItemMenu(item)), 
  1273. X               RootWindow(dpy, scr),
  1274. X               attributes.x, attributes.y, 
  1275. X               &x, &y, &child);
  1276. X     Leave((item->itemHeight / 2) + y)
  1277. X}
  1278. X
  1279. Xvoid SetInitialItem(menu, item)
  1280. XMenu *menu;
  1281. XMenuItem *item;
  1282. X{
  1283. X     extern char *realloc();
  1284. X     
  1285. X     Entry("SetInitialItem")
  1286. X
  1287. X     if (MenuHasInitialItem(menu)) {
  1288. X      if (strlen(MenuInitialItemText(menu)) < strlen(ItemText(item)))
  1289. X           MenuInitialItemText(menu) =
  1290. X            realloc(MenuInitialItemText(menu), 
  1291. X                strlen(ItemText(item)) + 1);
  1292. X     }
  1293. X     else
  1294. X      MenuInitialItemText(menu) =
  1295. X           allocate(char,(strlen(ItemText(item)) + 1));
  1296. X     strcpy(MenuInitialItemText(menu), ItemText(item));
  1297. X     Leave_void
  1298. X}
  1299. X
  1300. Xvoid ClearInitialItem(menu)
  1301. XMenu *menu;
  1302. X{
  1303. X     Entry("ClearInitialItem")
  1304. X
  1305. X     if (MenuHasInitialItem(menu)) {
  1306. X      free(MenuInitialItemText(menu));
  1307. X      MenuInitialItemText(menu) = (char *) NULL;
  1308. X     }
  1309. X     Leave_void
  1310. X}
  1311. X
  1312. XMenuItem *GetInitialItem(menu)
  1313. XMenu *menu;
  1314. X{
  1315. X     MenuItem *item;
  1316. X     
  1317. X     Entry("GetInitialItem")
  1318. X
  1319. X     if (MenuHasInitialItem(menu)) {
  1320. X      for(item = MenuItems(menu) ; item ; item = ItemNext(item)) {
  1321. X           if (ItemIsInitialItem(menu, item))
  1322. X            Leave(item)
  1323. X      }
  1324. X     }
  1325. X     Leave((MenuItem *) NULL)
  1326. X}
  1327. X
  1328. X
  1329. X/* Some utility functions */
  1330. X
  1331. Xvoid Retch(s, p1, p2, p3, p4)
  1332. Xchar *s;
  1333. Xlong p1, p2, p3, p4;
  1334. X{
  1335. X     char buffer[1024];
  1336. X     
  1337. X     sprintf(buffer, s, p1, p2, p3, p4);
  1338. X     fprintf(stderr, "Error in %s %s\n", curr_rtn(), buffer);
  1339. X     return;
  1340. X}
  1341. END_OF_awm/menus/menu.c
  1342. if test 34428 -ne `wc -c <awm/menus/menu.c`; then
  1343.     echo shar: \"awm/menus/menu.c\" unpacked with wrong size!
  1344. fi
  1345. # end of overwriting check
  1346. fi
  1347. echo shar: End of archive 11 \(of 13\).
  1348. cp /dev/null ark11isdone
  1349. MISSING=""
  1350. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do
  1351.     if test ! -f ark${I}isdone ; then
  1352.     MISSING="${MISSING} ${I}"
  1353.     fi
  1354. done
  1355. if test "${MISSING}" = "" ; then
  1356.     echo You have unpacked all 13 archives.
  1357.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1358. else
  1359.     echo You still need to unpack the following archives:
  1360.     echo "        " ${MISSING}
  1361. fi
  1362. ##  End of shell archive.
  1363. exit 0
  1364. Mike Wexler(wyse!mikew)    Phone: (408)433-1000 x1330
  1365.